/**
 * Session API Routes
 *
 * Handles session management with SQLite persistence
 */

import { Hono } from 'hono';
import type { ApiResponse, Session } from '@/types';
import { logger } from '@/utils/logger';
import { getSessionManager } from '@/db/session-manager';

export const sessionRoutes = new Hono();

// Get SessionManager instance
const sessionManager = getSessionManager();

/**
 * POST /api/session/create
 *
 * Create a new session
 */
sessionRoutes.post('/create', async (c) => {
  try {
    const body = await c.req.json();
    const { agentOptions = {}, metadata = {}, title, subAgentId } = body;

    const session = sessionManager.createSession(agentOptions, metadata, title, subAgentId);

    logger.info('Session created', { sessionId: session.id, title, subAgentId });

    const response: ApiResponse<Session> = {
      success: true,
      data: session,
      timestamp: new Date().toISOString(),
    };

    return c.json(response);
  } catch (error) {
    logger.error('Failed to create session', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'SESSION_CREATE_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

/**
 * GET /api/session/:id
 *
 * Get session details
 */
sessionRoutes.get('/:id', (c) => {
  const sessionId = c.req.param('id');

  const session = sessionManager.getSession(sessionId);

  if (!session) {
    const response: ApiResponse = {
      success: false,
      error: {
        code: 'SESSION_NOT_FOUND',
        message: `Session ${sessionId} not found`,
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 404);
  }

  const response: ApiResponse<Session> = {
    success: true,
    data: session,
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * DELETE /api/session/:id
 *
 * Delete a session
 */
sessionRoutes.delete('/:id', (c) => {
  const sessionId = c.req.param('id');

  const deleted = sessionManager.deleteSession(sessionId);

  if (!deleted) {
    const response: ApiResponse = {
      success: false,
      error: {
        code: 'SESSION_NOT_FOUND',
        message: `Session ${sessionId} not found`,
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 404);
  }

  const response: ApiResponse = {
    success: true,
    data: { sessionId, deleted: true },
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * GET /api/session
 *
 * List all sessions with pagination and filtering
 */
sessionRoutes.get('/', (c) => {
  const limit = parseInt(c.req.query('limit') || '20', 10);
  const offset = parseInt(c.req.query('offset') || '0', 10);
  const sortBy = (c.req.query('sortBy') || 'updatedAt') as 'createdAt' | 'updatedAt';
  const sortOrder = (c.req.query('sortOrder') || 'desc') as 'asc' | 'desc';
  const search = c.req.query('search');

  const result = sessionManager.listSessions({
    limit,
    offset,
    sortBy,
    sortOrder,
    search,
  });

  const response: ApiResponse<typeof result> = {
    success: true,
    data: result,
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * GET /api/session/stats
 *
 * Get session statistics
 */
sessionRoutes.get('/stats', (c) => {
  const stats = sessionManager.getStats();

  const response: ApiResponse<typeof stats> = {
    success: true,
    data: stats,
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

/**
 * POST /api/session/:id/message
 *
 * Add message to session
 */
sessionRoutes.post('/:id/message', async (c) => {
  try {
    const sessionId = c.req.param('id');
    const body = await c.req.json();
    const { role, content, metadata = {}, subAgentId } = body;

    if (!role || !content) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_REQUEST',
          message: 'role and content are required',
        },
        timestamp: new Date().toISOString(),
      };

      return c.json(response, 400);
    }

    const message = sessionManager.addMessage(sessionId, role, content, metadata, subAgentId);

    const response: ApiResponse<typeof message> = {
      success: true,
      data: message,
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 201);
  } catch (error) {
    logger.error('Failed to add message', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'MESSAGE_ADD_FAILED',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

/**
 * POST /api/session/:id/archive
 *
 * Archive a session
 */
sessionRoutes.post('/:id/archive', (c) => {
  const sessionId = c.req.param('id');

  const archived = sessionManager.archiveSession(sessionId);

  if (!archived) {
    const response: ApiResponse = {
      success: false,
      error: {
        code: 'SESSION_NOT_FOUND',
        message: `Session ${sessionId} not found`,
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 404);
  }

  const response: ApiResponse = {
    success: true,
    data: { sessionId, archived: true },
    timestamp: new Date().toISOString(),
  };

  return c.json(response);
});

